/*
    @file: log/include/SyncQueue.h
    @author: wolfhead
 */
#ifndef _LOG_SYNC_QUEUE_H_
#define _LOG_SYNC_QUEUE_H_

#include <boost/thread.hpp>
#include <boost/date_time.hpp>

namespace logger
{

template<typename T>
class SyncQueue
    : public boost::noncopyable
{
public:
    typedef std::list<T> QueueType;

    SyncQueue(size_t limit = 0)
        : limit_(limit)
    {

    }

    void push(const T& value)
    {
        boost::lock_guard<boost::mutex> lock(queue_lock_);
        list_.push_back(value);
        if (list_.size() >= limit_)
        {
            notify();
        }
    }

    int wait(unsigned int milliseconds)
    {
        boost::unique_lock<boost::mutex> lock(cond_lock_);
        if (milliseconds)
        {
            cond_.timed_wait(lock, boost::posix_time::milliseconds(milliseconds));
        }
        else
        {
            cond_.wait(lock);
        }
        return 0;
    }

    void notify()
    {
        cond_.notify_one();
    }

    int pop(T& value)
    {
        boost::lock_guard<boost::mutex> lock(queue_lock_);
        if (list_.size() == 0)
        {
            return -1;
        }
        else
        {
            value = list_.front();
            list_.pop_front();
        }
    }

    void split(QueueType& queue)
    {
        boost::lock_guard<boost::mutex> lock(queue_lock_);
        queue.splice(queue.begin(), list_);
    }

    void set_limit(size_t limit)
    {
        boost::lock_guard<boost::mutex> lock(queue_lock_);
        limit_ = limit;
    }

private:
    size_t limit_;
    QueueType list_;

    boost::mutex queue_lock_;
    boost::mutex cond_lock_;
    boost::condition_variable cond_;
};



}//namespace logger

#endif //#ifndef _LOG_SYNC_QUEUE_H_
